/**
 * 
 */
package GUI.GameBoard;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.OverlayLayout;
import javax.swing.WindowConstants;
import javax.swing.border.LineBorder;

import GUI.PlayerPanel.PlayerButton;
import Player.Human;
import Player.Player;
import Square.City;
import Square.Negotiable;
import Square.Square;
import Utils.Utils;

//VS4E -- DO NOT REMOVE THIS LINE!
public class GameSquare extends JPanel {

    private static final long serialVersionUID = 1L;
    private JPanel pnlColor;
    private JPanel pnlDetails;
    private PlayersSquarePanel pnlPlayers;
    private JPanel pnlSquare;
    private Square square;
    private JPanel pnlPicture;
    private String imgPath;
    private String imgLabel;
    private JLabel lblDetails;
    private final Color defColor = new Color(232, 232, 232);

    /**
     * Constructor for a Game Square with an input square
     * @param square A Game Square
     */
    public GameSquare(Square square) {
	// Initialize the Panels
	initComponents();

	// Initialize the Square Details
	initSquareDetails(square);
    }

    /**
     * Initializes the Components in the Panel
     */
    private void initComponents() {
	// Set a Preferred size Dimension for the Panel
	Dimension prefSize = new Dimension(320, 240);
	// Set the Preferred Size for this Panel
	setPreferredSize(prefSize);
	// Set the Layout to be Overlaying - Panel on top of Panel
	setLayout(new OverlayLayout(this));
	setBackground(defColor);
	// Add the Player Panel
	add(getPlayerPanel());
	// Add the Square Panel
	add(getSquarePanel());
    }

    /**
     * @return The Square Panel
     */
    private JPanel getSquarePanel() {
	if (pnlSquare == null) {
	    // Create a new Panel
	    pnlSquare = new JPanel();
	    // Set the Panel Layout
	    pnlSquare.setLayout(new BorderLayout());
	    // Make Transparent
	    pnlSquare.setOpaque(false);
	    // Add the Color Panel
	    pnlSquare.add(getPnColor(), BorderLayout.NORTH);
	    // Add the Details Panel
	    pnlSquare.add(getDetailsPanel(), BorderLayout.CENTER);
	}
	return pnlSquare;

    }

    /**
     * @return the Players Panel
     */
    private PlayersSquarePanel getPlayerPanel() {
	if (pnlPlayers == null) {
	    // Create a new Players Square Panel
	    pnlPlayers = new PlayersSquarePanel();
	    // Make sure the Panel is Transparent
	    pnlPlayers.setOpaque(false);
	}
	return pnlPlayers;
    }

    /**
     * Initialize the Square Details
     * @param square The Square to Show
     */
    private void initSquareDetails(Square square) {
	// Save the Square
	this.square = square;

	String squareDetails = "";

	try {
	    // Set the Square Color
	    setColor(square.getColor());

	    if (square.isAsset()) {
		// Set the Square Details
		squareDetails = "<HTML><P>" + ((Negotiable) square).getName() + "<BR>" + ((Negotiable) square).getCost() + "</P></HTML>";

	    } else {
		// Set the Square Details
		squareDetails = "<HTML><P>" + square.getName() + "</P></HTML>";
		setBackground(new Color(230, 220, 210));
	    }

	    // Set the Square Details
	    setDetails(squareDetails, square.getIcon());
	} catch (IllegalArgumentException e) {
	    Utils.writeText(square.getName(), "Is Positioned wrong...");
	}
    }

    /**
     * Create the Details Panel
     * @return The Details Panel
     */
    private JPanel getDetailsPanel() {
	// Check that the Panel is not initialized
	if (pnlDetails == null) {
	    // Create a new panel
	    pnlDetails = new JPanel(new BorderLayout());
	    // Set the Panel Properties
	    pnlDetails.setBorder(new LineBorder(Color.black, 1, false));
	    // Set the Preferred Size of the Panel
	    pnlDetails.setPreferredSize(new Dimension(270, 225));
	    // Set the Minimum Size - as Small as the Text on the Panel
	    pnlDetails.setMinimumSize(new Dimension(170, 125));
	    // Make Panel Transparent
	    pnlDetails.setOpaque(false);
	}
	return pnlDetails;
    }

    /**
     * @return The Details Label
     */
    private JLabel getlblDetails(String details) {
	if (lblDetails == null) {
	    // Create a New Label for the Details
	    lblDetails = new JLabel(details, JLabel.CENTER);
	    // Make Label Transparent
	    lblDetails.setOpaque(false);
	}
	return lblDetails;
    }

    /**
     * Create the Picture Panel
     * @return The Picture Panel
     */
    private JPanel getPnlPicture(String imagePath, String imageLabel) {
	if (pnlPicture == null) {
	    // Save the Image Path
	    imgPath = imagePath;
	    // Save the Image Label
	    imgLabel = imageLabel;
	    // Create a new Panel with Border LAyout
	    pnlPicture = new JPanel(new BorderLayout());
	    // Make transparent
	    pnlPicture.setOpaque(false);
	    // Get The Image
	    ImageIcon image = Utils.getImageIcon(imagePath);
	    // Check if the Image Exists
	    if (image != null) {
		// Set the Preferred Size by the Image
		pnlPicture.setPreferredSize(new Dimension(image.getIconWidth(), image.getIconHeight()));
		// Create an Image Label
		JLabel lblImage = new JLabel(image, JLabel.CENTER);
		// Set the Tool tip for the Image
		lblImage.setToolTipText(imageLabel);
		// Add the Image to the Panel
		pnlPicture.add(lblImage, BorderLayout.CENTER);
		// Add a Component Resize Listener
		pnlPicture.addComponentListener(new ResizeListener());
	    }
	}
	return pnlPicture;
    }

    /**
     * Returns the Image Path
     * @return The Image Path
     */
    private String getImagePath() {
	return imgPath;
    }

    /**
     * Returns the Image Tool tip Text
     * @return The Tool tip Image Text
     */
    private String getImageLabel() {
	return imgLabel;
    }

    /**
     * Create the Color Panel
     * @return The Color Panel
     */
    private JPanel getPnColor() {
	// Check that the Panel is not initialized
	if (pnlColor == null) {
	    // Create a new panel
	    pnlColor = new JPanel();
	    // Set the Panel Properties
	    pnlColor.setBorder(new LineBorder(Color.black, 1, false));
	    // Set the Panel Preferred Size
	    pnlColor.setPreferredSize(new Dimension(50, 15));
	}
	return pnlColor;
    }

    /**
     * Set the Color of the Colors Panel
     * @param color The Color to be Set
     */
    private void setColor(Color color) {
	// Set the Color Panel Background
	pnlColor.setBackground(color);
    }

    /**
     * Adds a New Player Button to the Square
     * @param player The Player to be Added
     */
    public PlayerButton addNewPlayerButton(Player player) {
	// Creates a new button for player
	PlayerButton newPlayer = new PlayerButton(player);
	// Add it to the Players Panel
	pnlPlayers.addPlayer(newPlayer);
	// Return the Player
	return newPlayer;
    }

    /**
     * Adds a Player Button to the Current Square
     * @param player The Player to be Added
     */
    public void movePlayerToSquare(PlayerButton player) {
	try {
	    Thread.sleep(200);
	} catch (InterruptedException e) {
	    e.printStackTrace();
	    Utils.writeText("error in moving player");
	}
	// Add a Player to the Square
	pnlPlayers.addPlayer(player);
	try {
	    // Repaint and Validate
	    Utils.repaintAndValidateAll(pnlPlayers);
	    Thread.sleep(200);
	} catch (InterruptedException ex) {
	    Logger.getLogger(GameSquare.class.getName()).log(Level.SEVERE, null, ex);
	}
    }

    /**
     * Removes a Player Button from the Current Square
     * @param player The Player to be Removed
     */
    public void movePlayerOffSquare(PlayerButton player) {
	// Remove a Player Off the Square
	pnlPlayers.removePlayer(player);
	try {
	    // Repaint and Validate
	    Utils.repaintAndValidateAll(pnlPlayers);
	    Thread.sleep(300);
	} catch (InterruptedException ex) {
	    Logger.getLogger(GameSquare.class.getName()).log(Level.SEVERE, null, ex);
	}
    }

    /**
     * Adds a House to the Square
     * @param numOfHouses The Number of houses Needed on the Asset
     */
    public void addHouse() {
	// Verify that this is an Asset
	if (square.isAsset()) {
	    // Adds another House to the Square
	    pnlPlayers.addHouse(((City) square).getNum_of_houses() + 1);
	}
    }

    /**
     * Clears all the Houses in the Square
     */
    private void clearHouses() {
	// Verify that this is an Asset
	if (square.isAsset()) {
	    pnlPlayers.clearHouses();
	}
    }

    /**
     * Set the Square Details
     * @param details The Details to be Set
     * @param imagePath The Image of the Square
     */
    private void setDetails(String details, String imagePath) {
	// Check that the Image Path is not Empty - There is an Icon to Insert
	if (imagePath != null) {
	    // Save the Image Icon Object
	    imgPath = imagePath;
	    // Create a New Image Panel and Add it
	    pnlDetails.add(getPnlPicture(imagePath, details), BorderLayout.CENTER);
	    // Repaint and Validate
	    Utils.repaintAndValidateAll(pnlDetails);
	}

	// Add the Details Label
	pnlDetails.add(getlblDetails(details), BorderLayout.SOUTH);

	// Add the Square Tool tip Details Text
	setSquareTooltipDetails();

    }

    /**
     * Sets the Square Details to the Tool tip
     * Saves the Square ToString Output to the Tool tip
     */
    private void setSquareTooltipDetails() {
	try {
	    // Set the Tool tip Text as the Square String
	    setToolTipText(Utils.StringToHTML(square.toString()));
	} catch (Exception e) {
	    System.out.println("Problem with " + square.getName());
	    e.printStackTrace();
	}

    }

    /**
     * Updates the Square Owner Border Color
     */
    public void updateOwner() {
	// TODO Player Button remains after buy
	// TODO Computer Player Dont Show Color
	// Check if the Square has any Owner
	if (square.getOwner() != null) {
	    // Get the Owner Player Color
	    Color playerColor = square.getOwner().getColor();
	    // Create a new Color like the Player Color with Alpha Transparency of 50
	    Color backColor = new Color(playerColor.getRed(), playerColor.getGreen(), playerColor.getBlue());
	    Color currBackColor = getBackground();

	    if (currBackColor.getRGB() != backColor.getRGB()) {
		this.setBackground(backColor.brighter());
	    }

	} else {
	    this.setBackground(defColor);
	}
	// Update the Square Tool tip to reflect the new Owner
	setSquareTooltipDetails();
	// Repaint and Validate
	Utils.repaintAndValidateAll(pnlPlayers);
	Utils.repaintAndValidateAll(this);
    }

    /**
     * Clear the Ownership Color of the Deleted Player on the Square
     * @param deleteColor The Color of the Delete Player
     */
    public void clearOwner(Color deleteColor) {
	// Verify that this
	if (square.getOwner() != null) {
	    // Check that the Current Square Color is the Color we need to Clear
	    if (square.getOwner().getColor().equals(deleteColor)) {
		// Clear the Background Color
		this.setBackground(null);
		// Set the Default Background Color
		this.setBackground(defColor);
		// Clear the Houses on this Square if Any
		clearHouses();
		// Update the Sqaure Tool tip Text
		setSquareTooltipDetails();
	    }
	}

    }

    public static void main(String[] args) {
	Square startsquare = new Square("Start");
	GameSquare square = new GameSquare(startsquare);
	JFrame frame = new JFrame();
	frame.getContentPane().setBackground(null);
	frame.getContentPane().add(square);
	frame.setSize(square.getPreferredSize());
	frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
	frame.setVisible(true);
//		Color backColor = new Color(70, 190, 164, 70);
//		square.setBackground(backColor);
	Human player = new Human("Assaf", 1500.1, Color.ORANGE, 1);

	PlayerButton pb1 = new PlayerButton(player);

	for (int i = 0; i < 30; ++i) {
	    square.movePlayerToSquare(pb1);

	    square.movePlayerOffSquare(pb1);
	}
    }

    /**
     * Resize listener to ensure image is sized correctly for the panel
     *
     */
    class ResizeListener extends ComponentAdapter {

	/**
	 * Overrides ComponentAdapter.componentResized
	 * Ensures the image is correctly resized
	 * @param evt the event
	 */
	@Override
	public void componentResized(ComponentEvent evt) {
	    // Notify that the Component Resized
	    super.componentResized(evt);
	    // Check if this Component is Our Panel
	    if (evt.getComponent() instanceof JPanel) {
		// Clear the Panel
		pnlPicture.removeAll();
		// Create a new Resized Image
		ImageIcon resizedIcon = Utils.createScaledIcon(getImagePath(), pnlPicture.getWidth(), pnlPicture.getHeight(), pnlPicture.getInsets());
		// Recreate the Picture Panel
		JLabel img = new JLabel(resizedIcon);
		img.setToolTipText(getImageLabel());
		pnlPicture.add(img, BorderLayout.CENTER);
		// Repaint and Validate
		Utils.repaintAndValidateAll(GameSquare.this);
	    }
	}
    }
}
